#include "learningenglish2.h"
#include <fstream>
#include <cmath>
#include <sstream>
#include <QMessageBox>
#include <set>
//#include <iostream>
using namespace std;

learningEnglish2::learningEnglish2(QWidget *parent)
    : QWidget(parent), p(0)
{
	ui.setupUi(this);
	connect(ui.pushButton, SIGNAL(clicked()), this, SLOT(pushButton_clicked()));
	connect(ui.lineEditTranslate, SIGNAL(returnPressed()), this, SLOT(pushButton_clicked()));
	connect(ui.lineEditTranslate, SIGNAL(textChanged(QString)), this, SLOT(lineEditTranslate_textChanged(QString)));
	//connect(ui.lineEditWord, SIGNAL(returnPressed()), this, SLOT(lineEditWord_returnPressed()));
	load();
	turn();
}

learningEnglish2::~learningEnglish2()
{
	save();
}

void learningEnglish2::load()
{
	//cout << "Идет загрузка англо-русского словаря...";
	{
		ifstream f("dictd_www.mova.org_slovnyk_en-ru.dict");
		string en;
		while (!f.eof())
		{
			string w;
			f >> w;
			if ((w.size() > 0))
			{
				if ((w[0] >= 'a') && (w[0] <= 'z'))
				{
					//en = "[en]" + w;
					en = w;
	//				cout << endl << "en: " << w << "\t";
				}
				else
				{
					dict[en].push_back(w);
	//				cout << "ru: " << w << "\t";
				}
			}
		}
		
	//	cout << endl;
//		f.close();
	//	cout << "успешно" << endl;
	}
	{
	//	cout << "Идет загрузка русско-английского словаря...";
		ifstream f("dictd_www.mova.org_slovnyk_ru-en.dict");
		string ru;
		while (!f.eof())
		{
			string w;
			f >> w;
			if ((w.size() > 0))
			{
				if ((w[0] >= 'a') && (w[0] <= 'z'))
				{
					dict[ru].push_back(w);
	//				cout << "en: " << w << "\t";
				}
				else
				{
					//ru = "[ru]" + w;
					ru = w;
	//				cout << endl << "ru: " << w << "\t";
				}
			}
		}
	//	cout << endl;
		//f.close();
	//	cout << "успешно" << endl;
	}
	
	{
	//	cout << "Идет загрузка частотного словаря...";
		ifstream fEn("enWorlds.txt");
		ifstream fRu("ruWorlds.txt");
		while (!fEn.eof() && !fRu.eof())
		{
			if (!fEn.eof())
			{
				string en;
				fEn >> en;
				for (string::iterator i = en.begin(); i != en.end(); ++i)
					*i = tolower(*i);
				//en = "[en]" + en;
		
				if (dict.find(en) != dict.end())
				{
	//				cout << en << " ";
	//				for (vector<string>::iterator j = dict[en].begin(); j != dict[en].end(); ++j)
	//					cout << *j << " ";
	//				cout << endl;
					words.push_back(en);
				}
			}
			if (!fRu.eof())
			{
				string ru;
				fRu >> ru;
				//ru = "[ru]" + ru;
				if (dict.find(ru) != dict.end())
				{
	//				cout << ru << " ";
	//				for (vector<string>::iterator j = dict[ru].begin(); j != dict[ru].end(); ++j)
	//					cout << *j << " ";
	//				cout << endl;
					words.push_back(ru);
				}
			}
		}
	//	f.close();
	//	cout << "успешно" << endl;
	//	cout << "Загружено слов: " << words.size() << endl;
	}

	{
		ifstream f("p.txt");
		f >> p;
	}
	
	{
		ifstream f("enru.txt");
		while (!f.eof())
		{
			char foo[1000];
			f.getline(foo, sizeof(foo));
			string en, ru;
			char * i = foo;
			while ((*i != '{') && (*i != ' ') && (*i != 0))
			{
				en += *i;
				++i;
			}
			if (*i == '{')
			{
				++i;
				while ((*i != '{') && (*i != ' ') && (*i != 0))
				{
					ru += *i;
					++i;
				}
			}
			if (!ru.empty() && !en.empty())
			{
	//			cout << en << " " << ru << endl;
				dict1[ru] = en;
				dict1[en] = ru;
			}
		}
	}
	
/*	
	for (int i = 0; i < 10000; ++i)
	{
		string en, ru;
		for (int j = 0; j <= rand() % 10; ++j)
			en += rand() % ('z' - 'a') + 'a';
		for (int j = 0; j <= rand() % 10; ++j)
			ru += rand() % ('z' - 'a') + 'a';
		enRuDict.push_back(pair<string, string>(en, ru));
	}
	*/
	
	
}

void learningEnglish2::save()
{
	ofstream f("p.txt");
	f << p;
}

string learningEnglish2::getTrans(int w)
{
	string s;
//	for (vector<string>::iterator i = dict[words[w]].begin(); i != dict[words[w]].end(); ++i)
//	{
//		if (!s.empty())
//			s += " ";
//		s += *i;
//	}
	set<string> tr;
	for (vector<string>::iterator i = dict[words[w]].begin(); i != dict[words[w]].end(); ++i)
		tr.insert(*i);
	if (tr.find(dict1[words[w]]) != tr.end())
	{
		tr.erase(dict1[words[w]]);
		if (!s.empty())
			s += " ";
		s += dict1[words[w]];
	}
	for (vector<string>::iterator i = words.begin(); i != words.end(); ++i)
		if (tr.find(*i) != tr.end())
		{
			if (dict.find(*i) != dict.end())
				for (vector<string>::iterator j = dict[*i].begin(); j != dict[*i].end(); ++j)
					if (words[w] == *j)
					{
						tr.erase(*i);
						if (!s.empty())
							s += " ";
						s += *i;
						break;
					}
		};
	for (vector<string>::iterator i = words.begin(); i != words.end(); ++i)
		if (tr.find(*i) != tr.end())
		{
			tr.erase(*i);
			if (!s.empty())
				s += " ";
			s += *i;
		};
	for (set<string>::iterator i = tr.begin(); i != tr.end(); ++i)
	{
		if (!s.empty())
			s += " ";
		s += *i;
	} 
	return s;
}

bool isEn(const QString s)
{
	return ((s[0] >= QChar('a')) && (s[0] <= QChar('z')));
}
bool isEn(const string &s)
{
	return ((s[0] >= 'a') && (s[0] <= 'z'));
}

void learningEnglish2::turn()
{
	string ansRu, ansEn;
	double r;
	if ((rand() % 3) || (errors.empty()))
	{
		r = 1.0 * rand() / RAND_MAX;
	 	w_ = static_cast<int>(sqrt(r) * p);
	 	if (w_ < 0)
	 		w_ = 0;
	 	if (w_ >= words.size())
	 		w_ = words.size() - 1;
	}
	else
	{
		w_ = errors.begin() -> first;
		r = 1.0 * w_ / p * w_ / p;
		errors.begin() -> second--;
		if (errors.begin() -> second == 0)
			errors.erase(errors.begin());
	}
	
	int c;
	if (p > 6)
 		c = static_cast<int>(r * 3);
 	else
 		c = 2;
 	string sw = getTrans(w_);
 	bool en = isEn(sw);
 	if (en)
 	{
 		ui.labelWordLang -> setText("[en]");
 		ui.labelTranslateLang1 -> setText("[ru]");
 		ui.labelTranslateLang2 -> setText("[ru]");
 		ui.labelTranslateLang3 -> setText("[ru]");
 	}
 	else
 	{
 		ui.labelWordLang -> setText("[ru]");
 		ui.labelTranslateLang1 -> setText("[en]");
 		ui.labelTranslateLang2 -> setText("[en]");
 		ui.labelTranslateLang3 -> setText("[en]");
 	}
 	
// 	if (qsw.size() > 100)
// 		qsw.resize(100);
	ui.labelWords -> setText(QString::fromUtf8(sw.c_str(), sw.size()));
	string foo2 = words[w_];
	word_ =  QString::fromUtf8(foo2.c_str(), foo2.size());
	switch (c)
	{
	case 0:
		ui.stackedWidget -> setCurrentIndex(2);
		// cout << words[w] << endl;
		break;
	case 1:
		{
			ui.stackedWidget -> setCurrentIndex(1);
			int t;
			t = rand() % 10;
			ui.listWidget -> clear();
			int i = 0;
			while (i < 10)
			{
				string s;
				if (t == i)
					ui.listWidget -> addItem(word_);
				else
				{
					s = words[rand() % words.size()];
					if (isEn(s) == en)
						continue;
					ui.listWidget -> addItem(QString::fromUtf8(s.c_str(), s.size()));
				}
				++i;
			}
		}
		break;
	case 2: 
		ui.stackedWidget -> setCurrentIndex(0);
		ui.labelTranslate -> setText(word_); 
		break;
	}
	int level = static_cast<int>(p / 10);
	ostringstream ss;
	ss << level;
	string s = ss.str();
	ui.labelLevel -> setText(QString::fromUtf8(s.c_str(), s.size()));
	ui.progressBar -> setValue(static_cast<int>(p * 10) % 100);
//	ui.lineEditWord -> setFocus();
//	ui.lineEditWord -> selectAll();
	ui.lineEditTranslate -> setFocus();
	ui.lineEditTranslate -> selectAll();
//	cin >> ansEn >> ansRu;
//	bool good = false;
//	for (vector<string>::iterator i = dict[words[w]].begin(); i != dict[words[w]].end(); ++i)
//		if (*i == ansRu)
//		{
//			good = true;
//			break;
//		}
//	if (good)
//	{
//		p += exp(-p / 100.0);
//		cout << ":) " << p << endl;
//	}
//	else
//	{
//		if (ansEn == "q")
//			done = true;
//		else
//		{
//			p -= exp(-p / 100.0) * 10;
//			cout << words[w] << " -> " << getTrans(w) << endl;
//			cout << p << " :((((((((((((((((((((( " << endl;
//		}
//	}
//	if (p < 0) 
//		p = 0;
//	if (p >= words.size()) 
//		p = words.size() - 1;
	
}

void learningEnglish2::pushButton_clicked()
{
	if (ui.lineEditTranslate -> text() == word_)
	{
		p += exp(-p / 100.0);
		
	}
	else
	{
		p -= exp(-p / 100.0) * 10;
		if (p < 0) 
			p = 0;
		errors[w_] += 3;
		QMessageBox::warning(this, "Mistake", word_, QMessageBox::Ok);
	}
	
	turn();
}

void learningEnglish2::lineEditWord_returnPressed()
{
	ui.lineEditTranslate -> setFocus();
}

QString learningEnglish2::changeLayout(const QString s)
{
	bool ie = isEn(word_);
	QString en = QString::fromUtf8("qwertyuiop[]asdfghjkl;'zxcvbnm,.");
	QString ru = QString::fromUtf8("йцукенгшщзхъфывапролджэячсмитьбю");
	map<QChar, QChar> m;
	QString::iterator i = en.begin(); QString::iterator j = ru.begin();
	for (;(i != en.end()) && (j != ru.end()); ++i, ++j)
	{
		if (ie)
			m[*j] = *i;
		else
			m[*i] = *j;
	} 
	QString result;
	for (QString::const_iterator i = s.begin(); i != s.end(); ++i)
	{
		
		if (m.find(i -> toLower()) != m.end())
			result += m[i -> toLower()];
		else
			result += i -> toLower();
	} 
	return result;
}

void learningEnglish2::lineEditTranslate_textChanged(QString s)
{
	
	ui.lineEditTranslate -> setText(changeLayout(s));
}
